#!/bin/bash -e

BLACK=`tput setaf 0`
RED=`tput setaf 1`
GREEN=`tput setaf 2`
YELLOW=`tput setaf 3`
BLUE=`tput setaf 4`
MAGENTA=`tput setaf 5`
CYAN=`tput setaf 6`
WHITE=`tput setaf 7`

BOLD=`tput bold`
RESET=`tput sgr0`

# for macos machines, we need proper OpenSSL...
OPENSSL_VERSION=$(openssl version -v)
if [[ "${OPENSSL_VERSION}" =~ ^LibreSSL.*$ ]]; then
  echo -e "${RED}ERROR: You may not have a compatible OpenSSL version (${OPENSSL_VERSION}). Please install OpenSSL version 1.0.2q or above.${RESET}"
  if [ $(uname) == 'Darwin' ]; then
        echo 'OpenSSL is required to build openBalena on macOS. To install with brew, run'
        echo ''
        echo '    brew install openssl'
        echo ''
    fi
  exit 1
fi

source "${BASH_SOURCE%/*}/_realpath"

domainResolves() {
  getent hosts "$1" > /dev/null 2>&1
}

CMD="$(realpath "$0")"
DIR="$(dirname "${CMD}")"
BASE_DIR="$(dirname "${DIR}")"
CONFIG_DIR="${BASE_DIR}/config"
CERTS_DIR="${CONFIG_DIR}/certs"

DOMAIN=openbalena.local

usage() {
  echo "usage: $0 [-c] [-h] [-p] [-d DOMAIN] -U EMAIL -P PASSWORD"
  echo
  echo "  -c           enable the ACME certificate service in staging or production mode."
  echo "  -p           patch hosts - patch the host /etc/hosts file"
  echo "  -d DOMAIN    the domain name this deployment will run as, eg. example.com. Default is 'openbalena.local'"
  echo "  -U EMAIL     the email address of the superuser account, used to login to your install from the Balena CLI"
  echo "  -P PASSWORD  the password to use for the superuser account."
  echo
}

show_help=false
patch_hosts=false
while getopts ":chpxd:U:P:" opt; do
  case "${opt}" in
    h) show_help=true;;
    p) patch_hosts=true;;
    x) set -x;;
    d) DOMAIN="${OPTARG}";;
    U) SUPERUSER_EMAIL="${OPTARG}";;
    P) SUPERUSER_PASSWORD="${OPTARG}";;
    c) ACME_CERT_ENABLED="true";;
    *)
      echo "Invalid argument: -${OPTARG}"
      usage
      exit 1
      ;;
  esac
done
shift $((OPTIND-1))

if [ -z "${SUPERUSER_EMAIL}" ] || [ -z "${SUPERUSER_PASSWORD}" ]; then
  usage
  exit 1
fi

if [ "$show_help" = "true" ]; then
  usage
  exit 1
fi

if [ ! -z "$ACME_CERT_ENABLED" ]; then
  echo "${BLUE}[INFO]${RESET} ACME Certificate request is ${BOLD}ENABLED${RESET}."
  
  if ! domainResolves "api.${DOMAIN}"; then
    echo "${YELLOW}[WARN]${RESET} Unable to resolve \"api.${DOMAIN}\"!"
    echo "${YELLOW}[WARN]${RESET} This might mean that you cannot use an ACME issued certificate."
  fi
fi

echo_bold() {
  echo "${BOLD}${@}${RESET}"
}

echo_bold "==> Creating new configuration at: $CONFIG_DIR"
mkdir -p "$CONFIG_DIR" "$CERTS_DIR"

echo_bold "==> Bootstrapping easy-rsa..."
source "${DIR}/ssl-common.sh"

echo_bold "==> Generating root CA cert..."
# shellcheck source=scripts/gen-root-ca
source "${DIR}/gen-root-ca" "${DOMAIN}" "${CERTS_DIR}"

echo_bold "==> Generating root cert chain for haproxy..."
# shellcheck source=scripts/gen-root-cert
source "${DIR}/gen-root-cert" "${DOMAIN}" "${CERTS_DIR}"

echo_bold "==> Generating token auth cert..."
# shellcheck source=scripts/gen-token-auth-cert
source "${DIR}/gen-token-auth-cert" "${DOMAIN}" "${CERTS_DIR}"

echo_bold "==> Generating VPN CA, cert and dhparam (this may take a while)..."
# shellcheck source=scripts/gen-vpn-certs
source "${DIR}/gen-vpn-certs" "${DOMAIN}" "${CERTS_DIR}"

echo_bold "==> Setting up environment..."
# shellcheck source=scripts/make-env
cat >"${CONFIG_DIR}/activate" <(source "${DIR}/make-env")

echo_bold "==> Adding default compose file..."
cp "${BASE_DIR}/compose/template.yml" "${CONFIG_DIR}/docker-compose.yml"

if [ "${patch_hosts}" = "true" ]; then
  echo_bold "==> Patching /etc/hosts..."
  # shellcheck source=scripts/patch-hosts
  source "${DIR}/patch-hosts" "${DOMAIN}"
fi

echo_bold "==> Success!"
echo '  - Start the instance with: ./scripts/compose up -d'
echo '  - Stop the instance with: ./scripts/compose stop'
echo '  - To create a single, flat, docker-compose.yml file, run:'
echo ''
echo '      ./scripts/compose config > docker-compose.yml'
echo ''

if [ -z "${ACME_CERT_ENABLED}" ]; then
  echo "  - Use the following certificate with Balena CLI: ${CERTS_DIR}/root/ca.crt"

  case $(uname) in
    Darwin)
      echo ''
      printf '    On macOS:\n\n'
      printf '      sudo security add-trusted-cert -d -r trustRoot -k "/Library/Keychains/System.keychain" "%s/root/ca.crt"\n' "${CERTS_DIR}"
      echo ''
      ;;
    *)
      ;;
  esac

  echo -e "    ${YELLOW}IMPORTANT:${RESET} You will need to restart your Docker daemon after trusting this certificate to allow your workstation to push images to the registry."
  echo ''
fi
